import subprocess

from dataclasses import dataclass, fields, asdict
import json

from typing import List


@dataclass(init=False)
class Autowired:

    kwargs: dict

    def __init__(self, **kwargs):
        self.kwargs = {}
        names = [field.name for field in fields(self)]
        for k, v in kwargs.items():
            if k in names:
                setattr(self, k, v)
            self.kwargs[k] = v
        

@dataclass(init=False)
class Default(Autowired):
    '''默认配置'''
    remote: str
    revision: str
    sync_j: str

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        names = [field.name for field in fields(self)]
        for k, v in kwargs.items():

            if k == "sync-j":
                self.sync_j = v
                continue

            if k in names:
                setattr(self, k, v)

    def fix(self, Manifest: "Manifest | None"):
        '''修复默认配置'''

        if "sync-j" not in self.kwargs.keys():
            self.sync_j = "4"
        else:
            self.sync_j = self.kwargs.get("sync-j")

@dataclass(init=False)
class Project(Autowired):
    '''对应一个项目'''
    name: str
    path: str
    remote: str
    revision: str

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        names = [field.name for field in fields(self)]
        for k, v in kwargs.items():
            if k in names:
                setattr(self, k, v)

    def fix(self, manifest: "Manifest | None"):
        '''修复项目'''
        if "path" not in self.kwargs.keys():
            self.path = self.name

        if "remote" not in self.kwargs.keys():
            self.remote = manifest.default.remote

        if "revision" not in self.kwargs.keys():
            self.revision = manifest.default.revision


@dataclass(init=False)
class Remote(Autowired):
    '''对应一个remote'''
    name: str
    fetch: str
    review: str

    def __init__(self, **kwargs):
        super().__init__(**kwargs)


@dataclass(init=False)
class Manifest(Autowired):
    default: Default
    project: List[Project]
    remote: List[Remote]

    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        names = [field.name for field in fields(self)]
        for key, value in kwargs.items():
            if key == "default":
                value = Default(**value)
                setattr(self, key, value)
                continue

            if key == "project":
                value = [Project(**project) for project in value]
                for project in value:
                    project.fix(self)
                setattr(self, key, value)
                continue
                
            if key == "remote":
                value = [Remote(**remote) for remote in value]
                setattr(self, key, value)
                continue

        if "default" not in self.kwargs.keys():
            self.default = Default()

        if "project" not in self.kwargs.keys():
            self.project = []
        
        if "remote" not in self.kwargs.keys():
            self.remote = []

class RepoUtil:

    def manifest() -> dict:
        return subprocess.check_output(["repo", "manifest", "--json"]).decode('utf-8')

    def Manifest() -> Manifest:
        manifest = json.loads(RepoUtil.manifest())
        return Manifest(**manifest)


if __name__ == "__main__":

    print(json.dumps([asdict(project) for project in RepoUtil.Manifest().project], indent=4))
